package com.sleepcamel.exporter.model;

import groovy.transform.EqualsAndHashCode;
import groovy.transform.ToString;

import com.sleepcamel.rest.domain.JavaClass;
import com.sleepcamel.rest.domain.JavaProperty;


@ToString(includeNames=true,includeFields=true,excludes="id,relationships,columnNameToPropertyMap,table,sequenceName,needsSequence")
@EqualsAndHashCode(includeFields=true,excludes="primitive,id,properties,relationships,columnNameToPropertyMap,table,sequenceName,needsSequence")
class JavaDBClass extends JavaClass{
    List<Relationship> relationships = []
    HashMap<String, JavaDBProperty> columnNameToPropertyMap = [:]
    Table table
    String sequenceName
    boolean needsSequence
	
	public JavaDBClass(){
		properties = new ArrayList<JavaDBProperty>();
	}
	
    public JavaDBClass(String name, String packageName) {
		this();
    	this.name = name
    	this.packageName = packageName
    }
	
    public boolean isNamesMatch() {
        return name == table.name;
    }

    String getDescriptivePropertyName() {
     JavaDBProperty p = this.properties.find{JavaDBProperty jp -> jp.name=="name"}
     if (p!=null) {
        return "name"
     }
     p = this.properties.find{JavaDBProperty jp -> jp.name=="title"}
     if (p!=null) {
      return "title"
     }

     for (JavaDBProperty pp : this.properties) {
       if (pp.name.endsWith("Name")) {
           return pp.name;
       }
     }

     return "id";
    }

    List<String> getSimplePropertyNames() {
        List<String> builder = []

        this.properties.each {JavaDBProperty jp ->
            switch (jp.javaClass) {
                case [new JavaDBClass("String","java.lang"), new JavaDBClass("Integer","java.lang"),
                new JavaDBClass("Long","java.lang"), new JavaDBClass("Byte", "java.lang"),
                new JavaDBClass("Date", "java.util")]:
                builder << jp.name
            }
            if (jp.javaClass.primitive) {
                builder << jp.name
            }
        }

        return builder
    }

    List<String> getPropertyNames() {
        List<String> builder = []
        this.relationships.each{Relationship relationship ->
            switch (relationship.type) {
                case[RelationshipType.MANY_TO_ONE, RelationshipType.ONE_TO_ONE]:
                    builder << relationship.name
            }
        }

        builder.addAll(getSimplePropertyNames())
        return builder
    }

    def validateClassAsModel () {
        assert this.id
        assert this.table
        assert this.name
        assert this.packageName
        this.relationships.each {Relationship relationship -> relationship.validate()}
    }

	public List<? extends JavaProperty> getAllProperties() {
		List<JavaProperty> allProperties = new ArrayList<JavaProperty>();
		allProperties.addAll(properties);
		for(Relationship relationship:relationships){
			if ( !relationship.ignore )
				allProperties.add(relationship.toJavaProperty());
		}
		return allProperties;
	}
}